package org.jupiter.blog.service.service.impl;

import org.jupiter.blog.api.convertor.JupiterPermissionUrlConvertor;
import org.jupiter.blog.api.domain.JupiterPermissionUrl;
import org.jupiter.blog.api.dto.JupiterPermissionUrlDTO;
import org.jupiter.blog.service.mapper.JupiterPermissionUrlMapper;
import org.jupiter.blog.service.service.JupiterPermissionUrlService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;

@Service
public class JupiterPermissionUrlServiceImpl implements JupiterPermissionUrlService {

	@Autowired
	private JupiterPermissionUrlMapper permissionUrlMapper;

	@Autowired
	private JupiterPermissionUrlConvertor permissionUrlConvertor;

	@Override
	@Transactional
	public void createPermissionUrl(JupiterPermissionUrlDTO dto) {
		JupiterPermissionUrl permissionUrl = permissionUrlConvertor.toEntity(dto);
		if (!StringUtils.hasText(permissionUrl.getUuid())){
			permissionUrl.setUuid(UUID.randomUUID().toString());
		}
		permissionUrl.setCreateTime(LocalDateTime.now());
		permissionUrlMapper.insert(permissionUrl);
	}

	@Override
	@Transactional(readOnly = true)
	public JupiterPermissionUrlDTO getById(String uuid) {
		JupiterPermissionUrl permissionUrl = permissionUrlMapper.selectByUuid(uuid);
		return permissionUrlConvertor.toDto(permissionUrl);
	}

	@Override
	@Transactional
	public void updatePermissionUrl(String uuid, JupiterPermissionUrlDTO dto) {
		JupiterPermissionUrl permissionUrl = permissionUrlConvertor.toEntity(dto);
		permissionUrl.setUuid(uuid);
		permissionUrlMapper.updateByUuidSelective(permissionUrl);
	}

	@Override
	@Transactional
	public void deletePermissionUrl(String uuid) {
		permissionUrlMapper.deleteByUuid(uuid);
	}

	@Override
	@Transactional(readOnly = true)
	public List<JupiterPermissionUrlDTO> getByPage(JupiterPermissionUrlDTO queryDTO) {
		int offset = (queryDTO.getPage() - 1) * queryDTO.getSize();
		List<JupiterPermissionUrl> permissionUrls = permissionUrlMapper.selectByPage(
				queryDTO.getPermissionUuid(),
				queryDTO.getUrlResourceUuid(),
				offset,
				queryDTO.getSize()
		);
		return permissionUrls.stream()
				.map(permissionUrlConvertor::toDto)
				.collect(Collectors.toList());
	}

	@Override
	@Transactional(readOnly = true)
	public long getCount(JupiterPermissionUrlDTO queryDTO) {
		return permissionUrlMapper.countByQuery(
				queryDTO.getPermissionUuid(),
				queryDTO.getUrlResourceUuid()
		);
	}

	@Override
	@Transactional(readOnly = true)
	public List<JupiterPermissionUrlDTO> getAll() {
		List<JupiterPermissionUrl> permissionUrls = permissionUrlMapper.selectAll();
		return permissionUrls.stream()
				.map(permissionUrlConvertor::toDto)
				.collect(Collectors.toList());
	}

	@Override
	@Transactional(readOnly = true)
	public List<JupiterPermissionUrlDTO> getByPermissionUuid(String permissionUuid) {
		List<JupiterPermissionUrl> permissionUrls = permissionUrlMapper.selectByPermissionUuid(permissionUuid);
		return permissionUrls.stream()
				.map(permissionUrlConvertor::toDto)
				.collect(Collectors.toList());
	}

	@Override
	@Transactional(readOnly = true)
	public List<JupiterPermissionUrlDTO> getByUrlResourceUuid(String urlResourceUuid) {
		List<JupiterPermissionUrl> permissionUrls = permissionUrlMapper.selectByUrlResourceUuid(urlResourceUuid);
		return permissionUrls.stream()
				.map(permissionUrlConvertor::toDto)
				.collect(Collectors.toList());
	}

	@Override
	@Transactional(readOnly = true)
	public JupiterPermissionUrlDTO getByPermissionAndUrlResource(String permissionUuid, String urlResourceUuid) {
		JupiterPermissionUrl permissionUrl = permissionUrlMapper.selectByPermissionAndUrlResource(permissionUuid,
				urlResourceUuid);
		return permissionUrlConvertor.toDto(permissionUrl);
	}

	@Override
	@Transactional
	public void deleteByPermissionUuid(String permissionUuid) {
		permissionUrlMapper.deleteByPermissionUuid(permissionUuid);
	}

	@Override
	@Transactional
	public void deleteByUrlResourceUuid(String urlResourceUuid) {
		permissionUrlMapper.deleteByUrlResourceUuid(urlResourceUuid);
	}

	@Override
	@Transactional
	public void batchCreatePermissionUrls(List<JupiterPermissionUrlDTO> dtos) {
		List<JupiterPermissionUrl> permissionUrls = dtos.stream()
				.map(dto -> {
					JupiterPermissionUrl permissionUrl = permissionUrlConvertor.toEntity(dto);
					if (!StringUtils.hasText(permissionUrl.getUuid())){
						permissionUrl.setUuid(UUID.randomUUID().toString());
					}
					permissionUrl.setCreateTime(LocalDateTime.now());
					return permissionUrl;
				})
				.collect(Collectors.toList());
		permissionUrlMapper.batchInsert(permissionUrls);
	}

	@Override
	@Transactional
	public void batchDeleteByPermissionUuid(String permissionUuid, List<String> urlResourceUuids) {
		permissionUrlMapper.batchDeleteByPermissionUuid(permissionUuid, urlResourceUuids);
	}

	@Override
	@Transactional
	public void assignUrlsToPermission(String permissionUuid, List<String> urlResourceUuids) {
		// 先删除现有的关联
		deleteByPermissionUuid(permissionUuid);

		// 批量创建新的关联
		if (urlResourceUuids != null && !urlResourceUuids.isEmpty()){
			List<JupiterPermissionUrlDTO> dtos = urlResourceUuids.stream()
					.map(urlResourceUuid -> {
						JupiterPermissionUrlDTO dto = new JupiterPermissionUrlDTO();
						dto.setPermissionUuid(permissionUuid);
						dto.setUrlResourceUuid(urlResourceUuid);
						return dto;
					})
					.collect(Collectors.toList());
			batchCreatePermissionUrls(dtos);
		}
	}
}
